package com.example.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.enums.ErrorCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.exception.CustomException;
import com.example.mapper.CartMapper;
import com.example.pojo.dto.CartQueryDto;
import com.example.pojo.entity.Account;
import com.example.pojo.entity.Cart;
import com.example.pojo.entity.User;
import com.example.pojo.vo.CartQueryVo;
import com.example.utils.AccountUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * 购物车 service 层实现类
 */
@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {

    @Resource
    private UserService userService;

    /**
     * 将一个宠物用品加入购物车
     *
     * @param cart 购物车
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Cart cart) {
        // 1.校验参数
        if (cart == null || cart.getGoodsId() == null || cart.getNum() == null) {
            throw new CustomException(ErrorCodeEnum.PARAM_LOST_ERROR);
        }
        // 2.获取当前用户且校验当前登录的账户是否是普通用户
        User dbUser = this.getUserAndCheck();

        // 3.获取看看
        Cart dbCart = this.lambdaQuery()
                .eq(Cart::getUserId, dbUser.getId())
                .eq(Cart::getGoodsId, cart.getGoodsId())
                .one();

        if (dbCart != null) {
            // 3.该宠物用品已在当前普通用户的购物车,则数量 + 1
            // 更新数据
            this.lambdaUpdate()
                    .eq(Cart::getUserId, dbUser.getId())
                    .eq(Cart::getGoodsId, cart.getGoodsId())
                    .set(Cart::getNum, dbCart.getNum() + cart.getNum())
                    .update();
        } else {
            // 4.宠物用品刚加入购物车时，宠物用品数量为 1
            // 4.1 构建参数
            dbCart = new Cart();
            // 普通用户id
            dbCart.setUserId(dbUser.getId());
            // 宠物用品id
            dbCart.setGoodsId(cart.getGoodsId());
            // 宠物用品数量
            dbCart.setNum(cart.getNum());
            // 4.2 存入数据库
            this.save(dbCart);
        }
    }


    /**
     * 查询购物车
     *
     * @param dto 条件
     * @return 宠物用品列表
     */
    @Override
    public List<CartQueryVo> query(CartQueryDto dto) {
        // 1.获取当前用户且校验当前登录的账户是否是普通用户
        User user = this.getUserAndCheck();

        // 2.当前普通用户只能查询自己的购物车
        dto.setUserId(user.getId());

        // 3.查询购物车
        return this.getBaseMapper().query(dto);
    }

    /**
     * 修改购物车中的宠物用品数量
     *
     * @param id 购物车id
     * @param updateNumber 变化的数量
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsNumber(Integer id, Integer updateNumber) {
        // 1.校验参数
        if (id == null) {
            throw new CustomException(ErrorCodeEnum.PARAM_LOST_ERROR);
        }

        // 2.校验当前登录的账户是否是普通用户
        this.getUserAndCheck();

        // 3.获取购物车数据
        Cart dbCart = this.lambdaQuery()
                .eq(Cart::getId, id)
                .one();
        if (dbCart == null) {
            throw new CustomException(ErrorCodeEnum.CART_DATA_NOT_EXITS);
        }

        // 4.更新后的宠物用品数量为0，删除这行数据
        int number = dbCart.getNum() + updateNumber;
        if (number == 0) {
            this.lambdaUpdate()
                    .eq(Cart::getId, id)
                    .remove();
        }

        // 5.修改购物车的宠物用品数量
        this.lambdaUpdate()
                .eq(Cart::getId, id)
                .set(Cart::getNum, number)
                .update();
    }

    /**
     * 将一种宠物用品移出购物车
     *
     * @param id 购物车id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer id) {
        // 1.校验参数
        if (id == null) {
            throw new CustomException(ErrorCodeEnum.PARAM_LOST_ERROR);
        }

        // 2.校验当前登录的账户是否是普通用户
        this.getUserAndCheck();

        // 3.将一种宠物用品移出购物车
        this.removeById(id);
    }

    /**
     * 将多种宠物用品移出购物车
     *
     * @param ids 购物车id列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Integer> ids) {
        // 1.校验当前登录的账户是否是普通用户
        this.getUserAndCheck();

        // 2.将多种宠物用品移出当前用户的购物车
        this.lambdaUpdate()
                .in(Cart::getId, ids)
                .remove();
    }

    /**
     * 校验当前登录的账户是否是普通用户
     *
     * @return 当前登录的普通用户
     */
    private User getUserAndCheck() {
        // 1.获取当前登录的账户
        Account currentLoginAccount = AccountUtils.getCurrentLoginAccount();
        if (currentLoginAccount == null) {
            throw new CustomException(ErrorCodeEnum.GET_CUR_USER_ERROR);
        }
        // 2.判断当前当前登录的是否是普通用户
        if (!RoleEnum.USER.name().equals(currentLoginAccount.getRole())) {
            throw new CustomException(ErrorCodeEnum.ONLY_USER_CART);
        }
        // 3.查询普通用户
        User dbUser = this.userService.lambdaQuery()
                .eq(User::getUsername, currentLoginAccount.getUsername())
                .one();
        if (dbUser == null) {
            throw new CustomException(ErrorCodeEnum.GET_CUR_USER_ERROR);
        }
        // 4.返回当前登录的普通用户
        return dbUser;
    }
}
